/**
 * Software License, Version 1.0
 * 
 * Copyright 2008 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgment:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgment may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or Granules, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called Granules, 
 * nor may Indiana University or Community Grids Lab or Granules appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 * LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 * WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 * NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 * INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 * INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 * "VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 * LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 * ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 * GENERATED USING SOFTWARE.
 */
package cgl.granules.scheduler;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import cgl.granules.util.MarshallingUtil;

/**
 * This class encapsulates various metrics associated with the resource.
 * 
 * @author Shrideep Pallickara
 * 
 */
public class ResourceMetrics {
	private int threadPoolSize;
	private int numOfProcessors;
	private int numberOfComputations;

	private long freeMemory;
	private long totalMemory;
	private long memoryUtilization;
	private String deploymentStream;

	private String moduleName = "ResourceMetrics: ";

	public ResourceMetrics(int threadPoolSize, String deploymentStream) {
		this.threadPoolSize = threadPoolSize;
		this.deploymentStream = deploymentStream;
		refresh();
	}

	public ResourceMetrics(byte[] marshalledBytes) throws IOException {
		ByteArrayInputStream baInputStream = new ByteArrayInputStream(
				marshalledBytes);
		DataInputStream din = new DataInputStream(new BufferedInputStream(
				baInputStream));
		MarshallingUtil marshaller = MarshallingUtil.getInstance();

		threadPoolSize = din.readInt();
		numOfProcessors = din.readInt();
		numberOfComputations = din.readInt();
		freeMemory = din.readLong();
		totalMemory = din.readLong();
		memoryUtilization = din.readLong();

		deploymentStream = marshaller.readString(din);

	}

	public byte[] getBytes() throws IOException {
		refresh();
		byte[] marshalledBytes = null;
		ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream();
		DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(
				baOutputStream));
		MarshallingUtil marshaller = MarshallingUtil.getInstance();

		dout.writeInt(threadPoolSize);
		dout.writeInt(numOfProcessors);
		dout.writeInt(numberOfComputations);
		dout.writeLong(freeMemory);
		dout.writeLong(totalMemory);
		dout.writeLong(memoryUtilization);
		marshaller.writeString(dout, deploymentStream);

		/** check to see if this is a request or response and do accordingly */
		dout.flush();
		marshalledBytes = baOutputStream.toByteArray();
		return marshalledBytes;
	}

	private void refresh() {
		Runtime runtime = Runtime.getRuntime();
		totalMemory = runtime.totalMemory() / (1024 * 1024);
		freeMemory = runtime.freeMemory() / (1024 * 1024);

		memoryUtilization = totalMemory - freeMemory;
		numOfProcessors = runtime.availableProcessors();
	}

	/**
	 * Retrieve the thread pool size.
	 * 
	 * @return the threadPoolSize
	 */
	public int getThreadPoolSize() {
		return threadPoolSize;
	}

	/**
	 * @return the deploymentStream
	 */
	public String getDeploymentStream() {
		return deploymentStream;
	}

	/**
	 * Retrieve the available free memory in MB.
	 * 
	 * @return the freeMemory
	 */
	public long getFreeMemory() {
		return freeMemory;
	}

	/**
	 * Retrieve the total memory assigned to the resource in MB.
	 * 
	 * @return the totalMemory
	 */
	public long getTotalMemory() {
		return totalMemory;
	}

	/**
	 * Retrieve the memory utilization in MB.
	 * 
	 * @return the memoryUtilization
	 */
	public long getMemoryUtilization() {
		return memoryUtilization;
	}

	/**
	 * Retrieve the number of processors available to this resource.
	 * 
	 * @return the numOfProcessors
	 */
	public int getNumberOfProcessors() {
		return numOfProcessors;
	}

	/**
	 * @return the numberOfComputations
	 */
	public int getNumberOfComputations() {
		return numberOfComputations;
	}

	/**
	 * @param numberOfComputations
	 *            the numberOfComputations to set
	 */
	public void setNumberOfComputations(int numberOfComputations) {
		this.numberOfComputations = numberOfComputations;
	}

	public String toString() {
		String stringRep = "";

		stringRep = "Deploymment Stream =" + deploymentStream
				+ "\nNumber Of Processor=" + numOfProcessors
				+ "\nMemory Utilization=" + memoryUtilization
				+ "MB, Free Memory=" + freeMemory + "MB, Total Memory="
				+ totalMemory + "MB, \nThread Pool Size = " + threadPoolSize
				+ "\nNumber Of Computations = " + numberOfComputations;

		return stringRep;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
